<?php

namespace app\common\controller;

use think\Controller;
use think\Validate;
use app\model\Log;

class _BaseController extends Controller
{   
	public $action;
	public $data;
	public $id;
	public $page;
	public $size;
	public $token;
	public $user;


	protected function initialize()
	{   
		// 跨域
		// header('Access-Control-Allow-Origin: *');
		// 方法
		$this->action = request()->action(true);
		// 提取token
		$this->getToken();
		// 数据过滤
		$this->filterData();
	}

	/**
	 * 错误返回
	 * @param  string $error 错误信息
	 * @return json
	 */
	protected function resError($error = '',$code = 304)
	{	
		json(reponse($code, [], $error))->send();
		exit();
	}

	/**
	 * 成功返回
	 * @param  array  $send         返回的数据
	 * @return array
	 */
	protected function resSuccess($data = [] ,$code = 200)
	{   
		
		$this->recordLog($data);
		return reponse($code, $data);
	}

	/**
	 * 记录日志
	 * @param  array  $send         返回的数据
	 * @return array
	 */
	protected function recordLog($data = [])
	{   
		if($this->user){
			$log['user_id'] = $this->user['id'];
			$log['user_name'] = $this->user['name'];
			$log['user_type'] = $this->user['type'];
			$log['path'] = '/'.$this->request->path();
			$log['data'] = $this->data && strpos($log['path'],'upload')===false?serialize($this->data):'';
			Log::doCreate($log);
		}
		return;
	}

	/**
	 * 提取token
	 */
	protected function getToken()
	{   
		$this->token = request()->param(config('params.token_field'));
	}

	/**
	 * 参数过滤
	 * @param  string $method 类型
	 */
	protected function filterData($method = 'param')
	{   
		if(!empty($this->scene[$this->action])){
			$field = $this->scene[$this->action];
			$this->data = request()->only($field,$method);
		}
	}

	/**
	 * 声明关键参数 id,page,size.. params 设置 
	 * 并转$this->data 为 obj
	 * @param  string $method 类型
	 */
	protected function stateKeyField()
	{   
		$field = config('params.state_key_field');

		if($this->data){
			if($field && is_array($field)){
				foreach ($this->data as $key => $value) {
					if(in_array($key, $field) && strlen($value) > 0 && property_exists($this,$key)){
						$this->$key = $value;
						unset($this->data[$key]);
					}
				}
			}
		}

	}

	/**
	 * 验证码唯一性处理
	 * @param  string $method 类型
	 */
	protected function verify()
	{   
		if(!empty($this->data['verifycode']) && !empty($this->data['verifykey'])){
			$this->replaceRule('verifycode','captcha','captcha:'.$this->data['verifykey']);
		}
	}

	/**
	 * 添加验证规则 自动注册自定义规则 不能和已有函数重名
	 * @param  string $ruleName 验证规则名称
	 * @param  string $ruleType 验证规则类型 可以使单条 也可以是多条 用 | 分割
	 */
	protected function appendRule($ruleName,$ruleType)
	{
		foreach ($this->rule as $ruleField => &$type) {
			list($name,$field) = explode('|', $ruleField);
			if($name == $ruleName){
				$ruleType = explode('|', $ruleType);
				
				foreach ($ruleType as $value) {
					if (strpos($value, "check")===0) {
						if(is_callable([$this,$value])) call_user_func([$this,$value]);
					}
					if (strpos($value, "requireCallback:")===0) {
						$fun = substr($value,strlen("requireCallback:"));
						if(is_callable([$this,$fun])) call_user_func([$this,$fun]);
					}
				}
				$type = explode('|', $type);
				$type = array_merge($type,$ruleType);
				$type = trim(implode('|', $type),'|');
				break;
			}
		}

	}

	/**
	 * 删除验证规则
	 * @param  string $ruleName 验证规则名称
	 * @param  string $ruleType 验证规则类型 可以使单条 也可以是多条 用 | 分割
	 */
	protected function removeRule($ruleName,$ruleType)
	{
		foreach ($this->rule as $ruleField => &$type) {
			list($name,$field) = explode('|', $ruleField);
			if($name == $ruleName){
				$type = explode('|', $type);
				$ruleType = explode('|', $ruleType);
				foreach ($ruleType as $value) {
					$key = array_search($value,$type);
					if($key !== false) unset($type[$key]);
				}
				$type = trim(implode('|', $type),'|');
				break;
			}
		}
	}

	/**
	 * 替换验证规则
	 * @param  string $ruleName 验证规则名称
	 * @param  string $ruleType 验证规则类型
	 */
	protected function replaceRule($ruleName,$before_ruleType,$after_ruleType)
	{
		foreach ($this->rule as $ruleField => &$type) {
			list($name,$field) = explode('|', $ruleField);
			if($name == $ruleName){
				$type = explode('|', $type);
				$key = array_search($before_ruleType,$type);
				$type = array_replace($type, [$key => $after_ruleType]);
				$type = trim(implode('|', $type),'|');
				break;
			}
		}
	}

	/**
	 * 数据验证
	 * @param  string $ruleName 验证规则名称
	 * @param  string $ruleType 验证规则类型
	 */
	protected function check()
	{
		$v = Validate::make($this->rule);
		if (!$v->check($this->data)) {
			$this->resError($v->getError());
		}
		$this->stateKeyField();
	}
}
